#include "settingsview.h"
#include "globaltype.h"
#include "ui_settingsview.h"
#include "usersettings.h"
#include "utils/utils.h"
#include <QDir>
#include <QFileDialog>
#include <QSettings>
#include <QSlider>
#include <QSpinBox>
#include <QStandardPaths>
#include <QStorageInfo>
#include <QTimer>

SettingsView::SettingsView(QWidget* parent) : ScrollView { parent }, ui(new Ui::SettingsView)
{
    ui->setupUi(client());

    // 设置控件的样式类
    // 设置标题标签类
    ui->presenter_list_label->setProperty("class", "settingTitle");
    ui->screen_capture_label->setProperty("class", "settingTitle");
    // 设置只读属性
    ui->video_dir_edit->setProperty("readOnly", true);
    ui->screen_capture_dir_edit->setProperty("readOnly", true);
    // 设置磁盘空间和警告标签类
    ui->video_dir_warning_label->setProperty("class", "warningText");
    ui->recorder_count_warning_label->setProperty("class", "warningText");
    ui->screen_capture_dir_warning_label->setProperty("class", "warningText");
    ui->status_label->setProperty("class", "successText");

    // 根据内存大小设置监视数量的范围
    int count = 2;
    qint64 total_memory = utils::getTotalSystemMemory();
    if (total_memory > 0) {
        constexpr qint64 memory_threshold = 2LL * Constants::GB; // 4GB in bytes
        count = static_cast<int>(total_memory / memory_threshold);
    }
    ui->recorder_count_slider->setRange(1, count);
    ui->recorder_count_spinbox->setRange(1, count);

    ui->audio_sample_rate_combo->addItem(tr("44.1 kHz"), 44100);
    ui->audio_sample_rate_combo->addItem(tr("48 kHz"), 48000);
    ui->audio_sample_rate_combo->addItem(tr("96 kHz"), 96000);
    ui->audio_sample_rate_combo->setCurrentIndex(1); // 默认选择48kHz
    ui->audio_bitrate_combo->addItem(tr("Low (96 kbps)"), 96000);
    ui->audio_bitrate_combo->addItem(tr("Medium (128 kbps)"), 128000);
    ui->audio_bitrate_combo->addItem(tr("High (192 kbps)"), 192000);
    ui->audio_bitrate_combo->addItem(tr("Very High (256 kbps)"), 256000);
    ui->audio_bitrate_combo->setCurrentIndex(1); // 默认128kbps
    ui->audio_channels_combo->addItem(tr("Mono (1 channel)"), 1);
    ui->audio_channels_combo->addItem(tr("Stereo (2 channels)"), 2);
    ui->audio_channels_combo->setCurrentIndex(1); // 默认立体声
    ui->resolution_combo->addItem(tr("Original"), "original");
    ui->resolution_combo->addItem(tr("1080p (1920×1080)"), "1080p");
    ui->resolution_combo->addItem(tr("720p (1280×720)"), "720p");
    ui->resolution_combo->addItem(tr("480p (854×480)"), "480p");
    ui->resolution_combo->setCurrentIndex(0); // 默认使用原始分辨率
    ui->video_bitrate_combo->addItem(tr("Low (3 Mbps)"), 3000000);
    ui->video_bitrate_combo->addItem(tr("Medium (8 Mbps)"), 8000000);
    ui->video_bitrate_combo->addItem(tr("High (15 Mbps)"), 15000000);
    ui->video_bitrate_combo->addItem(tr("Ultra (30 Mbps)"), 30000000);
    ui->video_bitrate_combo->setCurrentIndex(1); // 默认中等比特率
    ui->frame_rate_combo->addItem(tr("15 fps"), 15.0);
    ui->frame_rate_combo->addItem(tr("24 fps"), 24.0);
    ui->frame_rate_combo->addItem(tr("30 fps"), 30.0);
    ui->frame_rate_combo->addItem(tr("60 fps"), 60.0);
    ui->frame_rate_combo->setCurrentIndex(2); // 默认30fps
    ui->quality_preset_combo->addItem(tr("Custom"), "custom");
    ui->quality_preset_combo->addItem(tr("High Quality"), "high");
    ui->quality_preset_combo->addItem(tr("Balanced"), "balanced");
    ui->quality_preset_combo->addItem(tr("Low Size"), "low");
    ui->quality_preset_combo->addItem(tr("Web Optimized"), "web");
    ui->quality_preset_combo->setCurrentIndex(0); // 默认自定义

    // 初始化设置值
    loadSettings();

    // 连接信号槽 - 双向同步滑块和数值框
    connect(ui->recorder_count_slider, &QSlider::valueChanged, ui->recorder_count_spinbox,
            &QSpinBox::setValue);
    connect(ui->recorder_count_spinbox, QOverload<int>::of(&QSpinBox::valueChanged),
            ui->recorder_count_slider, &QSlider::setValue);

    // 连接信号槽 - 自动保存设置
    connect(ui->recorder_count_spinbox, QOverload<int>::of(&QSpinBox::valueChanged), this,
            &SettingsView::autoSaveRecorderSettings);

    // 连接视频路径选择按钮
    connect(ui->video_dir_button, &QPushButton::clicked, this, &SettingsView::selectVideoDir);

    // 连接屏幕捕获路径选择按钮
    connect(ui->screen_capture_dir_button, &QPushButton::clicked, this,
            &SettingsView::selectScreenCapturePath);

    connect(ui->quality_preset_combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
            &SettingsView::applyPreset);
    connect(ui->audio_sample_rate_combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
            &SettingsView::autoSaveAudioSettings);
    connect(ui->audio_bitrate_combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
            &SettingsView::autoSaveAudioSettings);
    connect(ui->audio_channels_combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
            &SettingsView::autoSaveAudioSettings);
    connect(ui->resolution_combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
            &SettingsView::autoSaveVideoSettings);
    connect(ui->video_bitrate_combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
            &SettingsView::autoSaveVideoSettings);
    connect(ui->frame_rate_combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
            &SettingsView::autoSaveVideoSettings);
}

SettingsView::~SettingsView()
{
    delete ui;
}

void SettingsView::loadSettings()
{
    // 加载实时监测设置
    ui->recorder_count_spinbox->setValue(
            UserSettings::instance().newRecorderSettings().recorder_count);
    ui->recorder_count_slider->setValue(
            UserSettings::instance().newRecorderSettings().recorder_count);

    // 加载视频保存路径
    const QDir& video_dir = UserSettings::instance().newRecorderSettings().video_save_dir;
    ui->video_dir_edit->setText(video_dir.absolutePath());
    validateVideoDir(video_dir, ui->video_dir_warning_label);

    // 加载上次保存路径
    const QDir& save_dir = UserSettings::instance().screenCaptureSettings().save_dir;
    ui->screen_capture_dir_edit->setText(save_dir.absolutePath());
    validateVideoDir(save_dir, ui->screen_capture_dir_warning_label);

    const auto& scs = UserSettings::instance().screenCaptureSettings();
    ui->audio_sample_rate_combo->setCurrentIndex(
            ui->audio_sample_rate_combo->findData(scs.audio.sample_rate));
    ui->audio_bitrate_combo->setCurrentIndex(ui->audio_bitrate_combo->findData(scs.audio.bitrate));
    ui->audio_channels_combo->setCurrentIndex(
            ui->audio_channels_combo->findData(scs.audio.channels));
    ui->resolution_combo->setCurrentIndex(ui->resolution_combo->findData(scs.video.resolution));
    ui->video_bitrate_combo->setCurrentIndex(ui->video_bitrate_combo->findData(scs.video.bitrate));
    ui->frame_rate_combo->setCurrentIndex(ui->frame_rate_combo->findData(scs.video.frame_rate));
}

void SettingsView::autoSaveRecorderSettings()
{
    RecorderSettings rs { UserSettings::instance().newRecorderSettings() };
    rs.recorder_count = ui->recorder_count_spinbox->value();
    UserSettings::instance().setNewRecorderSettings(rs);
    UserSettings::instance().save();

    ui->status_label->setText(tr("The changes are saved and take effect after the restart."));
    QTimer::singleShot(5000, ui->status_label, &QLabel::clear);
}

void SettingsView::autoSaveAudioSettings()
{
    ScreenCaptureSettings scs { UserSettings::instance().screenCaptureSettings() };
    scs.audio.sample_rate = ui->audio_sample_rate_combo->currentData().toInt();
    scs.audio.bitrate = ui->audio_bitrate_combo->currentData().toInt();
    scs.audio.channels = ui->audio_channels_combo->currentData().toInt();
    UserSettings::instance().setScreenCaptureSettings(scs);
    UserSettings::instance().save();
}

void SettingsView::autoSaveVideoSettings()
{
    ScreenCaptureSettings scs { UserSettings::instance().screenCaptureSettings() };
    scs.video.resolution = ui->resolution_combo->currentData().toString();
    scs.video.bitrate = ui->video_bitrate_combo->currentData().toInt();
    scs.video.frame_rate = ui->frame_rate_combo->currentData().toInt();
    UserSettings::instance().setScreenCaptureSettings(scs);
    UserSettings::instance().save();
}

void SettingsView::autoSaveScreenCaptureSettings()
{
    ScreenCaptureSettings scs { UserSettings::instance().screenCaptureSettings() };
    scs.audio.sample_rate = ui->audio_sample_rate_combo->currentData().toInt();
    scs.audio.bitrate = ui->audio_bitrate_combo->currentData().toInt();
    scs.audio.channels = ui->audio_channels_combo->currentData().toInt();
    scs.video.resolution = ui->resolution_combo->currentData().toString();
    scs.video.bitrate = ui->video_bitrate_combo->currentData().toInt();
    scs.video.frame_rate = ui->frame_rate_combo->currentData().toInt();
    UserSettings::instance().setScreenCaptureSettings(scs);
    UserSettings::instance().save();
}

void SettingsView::selectVideoDir()
{
    QString current_dir = ui->video_dir_edit->text();
    if (current_dir.isEmpty()) {
        current_dir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
    }

    const QString path = QFileDialog::getExistingDirectory(
            this, tr("Select the video save directory"), current_dir,
            QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    if (!path.isEmpty()) {
        ui->video_dir_edit->setText(path);

        // 验证选择的目录
        QDir dir { path };
        if (validateVideoDir(dir, ui->video_dir_warning_label)) {
            // 保存设置
            RecorderSettings rs { UserSettings::instance().newRecorderSettings() };
            rs.video_save_dir = path;
            UserSettings::instance().setNewRecorderSettings(rs);
            UserSettings::instance().save();

            ui->status_label->setText(
                    tr("The changes are saved and take effect after the restart."));
            QTimer::singleShot(5000, ui->status_label, &QLabel::clear);
        }
    }
}

void SettingsView::selectScreenCapturePath()
{
    QString current_dir = ui->screen_capture_dir_edit->text();
    if (current_dir.isEmpty()) {
        current_dir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
    }

    const QString path = QFileDialog::getExistingDirectory(
            this, tr("Select the screen capture save directory"), current_dir,
            QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    if (!path.isEmpty()) {
        ui->screen_capture_dir_edit->setText(path);

        const QDir dir { path };
        if (validateVideoDir(dir, ui->screen_capture_dir_warning_label)) {
            // 保存设置
            ScreenCaptureSettings scs { UserSettings::instance().screenCaptureSettings() };
            scs.save_dir = path;
            UserSettings::instance().setScreenCaptureSettings(scs);
            UserSettings::instance().save();

            ui->status_label->setText(
                    tr("The changes are saved and take effect after the restart."));
            QTimer::singleShot(5000, ui->status_label, &QLabel::clear);
        }
    }
}

void SettingsView::applyPreset(int index)
{
    if (index <= 0)
        return; // 自定义模式不更改设置

    QString preset = ui->quality_preset_combo->itemData(index).toString();

    if (preset == "high") {
        // 高质量预设
        ui->resolution_combo->setCurrentIndex(0); // 原始分辨率
        ui->video_bitrate_combo->setCurrentIndex(2); // 高比特率
        ui->frame_rate_combo->setCurrentIndex(3); // 60fps
        ui->audio_sample_rate_combo->setCurrentIndex(2); // 96kHz
        ui->audio_bitrate_combo->setCurrentIndex(3); // 256kbps
        ui->audio_channels_combo->setCurrentIndex(1); // 立体声
    } else if (preset == "balanced") {
        // 平衡预设
        ui->resolution_combo->setCurrentIndex(1); // 1080p
        ui->video_bitrate_combo->setCurrentIndex(1); // 中等比特率
        ui->frame_rate_combo->setCurrentIndex(2); // 30fps
        ui->audio_sample_rate_combo->setCurrentIndex(1); // 48kHz
        ui->audio_bitrate_combo->setCurrentIndex(1); // 128kbps
        ui->audio_channels_combo->setCurrentIndex(1); // 立体声
    } else if (preset == "low") {
        // 低体积预设
        ui->resolution_combo->setCurrentIndex(2); // 720p
        ui->video_bitrate_combo->setCurrentIndex(0); // 低比特率
        ui->frame_rate_combo->setCurrentIndex(1); // 24fps
        ui->audio_sample_rate_combo->setCurrentIndex(0); // 44.1kHz
        ui->audio_bitrate_combo->setCurrentIndex(0); // 96kbps
        ui->audio_channels_combo->setCurrentIndex(0); // 单声道
    } else if (preset == "web") {
        // 网络优化预设
        ui->resolution_combo->setCurrentIndex(2); // 720p
        ui->video_bitrate_combo->setCurrentIndex(0); // 低比特率
        ui->frame_rate_combo->setCurrentIndex(2); // 30fps
        ui->audio_sample_rate_combo->setCurrentIndex(1); // 48kHz
        ui->audio_bitrate_combo->setCurrentIndex(1); // 128kbps
        ui->audio_channels_combo->setCurrentIndex(1); // 立体声
    }

    // 重置为自定义模式，这样用户可以在预设基础上调整
    ui->quality_preset_combo->setCurrentIndex(0);

    autoSaveScreenCaptureSettings();
}

bool SettingsView::validateVideoDir(const QDir& dir, QLabel* warning_label)
{
    // 检查目录是否有效
    if (!dir.exists()) {
        if (!dir.mkpath(".")) {
            warning_label->setText(
                    tr("Warning: Cannot create directory, please check permissions."));
            warning_label->setProperty("class", "errorText");
            warning_label->style()->unpolish(warning_label);
            warning_label->style()->polish(warning_label);
            return false;
        }
    }

    // 检查是否为系统目录
    if (utils::isSystemDrive(dir.absolutePath())) {
        warning_label->setText(
                tr("Warning: Avoid selecting the system directory as the video save location."));
        warning_label->setProperty("class", "errorText");
        warning_label->style()->unpolish(warning_label);
        warning_label->style()->polish(warning_label);
        return true; // 虽然不推荐，但仍然可用
    }

    // 检查磁盘空间
    QStorageInfo storage(dir);
    if (storage.isValid() && storage.isReady()) {
        qint64 available_space = storage.bytesAvailable();
        qint64 required_space = 10 * 1024 * 1024 * 1024LL; // 10GB
        if (available_space < required_space) {
            double gbAvailable = available_space / (1024.0 * 1024.0 * 1024.0);
            warning_label->setText(
                    tr("Note: The remaining disk space is only % 1GB, it is recommended to reserve "
                       "at least 10GB for video storage.")
                            .arg(gbAvailable, 0, 'f', 1));
            warning_label->setProperty("class", "warningText");
            warning_label->style()->unpolish(warning_label);
            warning_label->style()->polish(warning_label);
            return true;
        }
    }

    // 一切正常
    warning_label->clear();
    return true;
}
